function Promise(executor) {
  let that = this;
  that.status = 'pending';
  that.value = undefined;
  that.reason = undefined;
  that.onResolvedCallbacks = [];
  that.onRejectedCallbacks = [];
  function resolve(value) {
    if (that.status === 'pending') {
      that.status = 'fulfilled';
      that.value = value;
    }
    that.onResolvedCallbacks.forEach(function (fn) {
      fn();
    });
  }
  function reject(reason) {
    if (that.status === 'pending') {
      that.status = 'rejected';
      that.reason = reason;
    }
    that.onRejectedCallbacks.forEach(function (fn) {
      fn();
    });
  }
  try {
    executor(resolve, reject);
  } catch (e) {
    reject(e);
  }
}
// 我这个resolvePromise方法 可能还会集成别人的promise, 为了可以和别人的promise混用
function resolvePromise(promise2, x, resolve, reject) {
  if(promise2 === x){ // 如果自己等待自己 就直接变成失败态
    return reject(new TypeError('循环引用'))
  }
  // 1.判断x 是不是一个promise
  if( (typeof x === 'object' && x!==null) || typeof x === 'function'){
    // 有可能是一个promise 
    try{
      let then = x.then; // 取出then方法 {then:function(){}} 有可能会发生异常
      if (typeof then === 'function') { // 就是promise
        then.call(x, function (y) { // 如果当前x 是promise 就让这个promise 执行
          // 递归解析
          resolvePromise(promise2, y, resolve, reject); // 成功传递给成功
        }, function (r) {
          reject(r); // 失败传递给失败
        })
      } else {
        resolve(x);
      }
    }catch(e){
      reject(e);
    }
  }else{
    resolve(x);
  }
}
// then方法是异步的
Promise.prototype.then = function (onFulfiled, onRejected) {
  let that = this;
  let promise2;
  // 当前调用then方法后 会返回一个全新的promise
  // 应该多一个判断 判断 x 是不是一个promise，如果是promise 那就采用当前promise的状态
  promise2 = new Promise(function (resolve, reject) {
    if (that.status === 'fulfilled') {
      setTimeout(() => {
        try {
          let x = onFulfiled(that.value); // x=100;
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      }, 0);
    }
    if (that.status === 'rejected') {
      setTimeout(() => {
        try {
          let x = onRejected(that.reason);
          resolvePromise(promise2, x, resolve, reject);
        } catch (e) {
          reject(e);
        }
      }, 0);
    }
    if (that.status === 'pending') {
      that.onResolvedCallbacks.push(function () {
        setTimeout(() => {
          try {
            let x = onFulfiled(that.value); // x=100;
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      });
      that.onRejectedCallbacks.push(function () {
        setTimeout(() => {
          try {
            let x = onRejected(that.reason);
            resolvePromise(promise2, x, resolve, reject);
          } catch (e) {
            reject(e);
          }
        }, 0);
      })
    }
  });
  return promise2;
}
module.exports = Promise;